/**
 * huanglu1 2018年4月29日
 */
package com.stars.common;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author huanglu1
 * @date 2018年4月29日
 */
public class SccbvDateUtils {

	/**
	 * yyyy-MM-dd HH:mm:ss
	 */
	public static final String PATTERN_NORMAL_DATETIME_NINETEEN = "yyyy-MM-dd HH:mm:ss";

	/**
	 * yyyy-MM-dd
	 */
	public static final String PATTERN_NORMAL_DATE_TEN = "yyyy-MM-dd";

	/**
	 * HH:mm:ss
	 */
	public static final String PATTERN_NORMAL_TIME_EIGHT = "HH:mm:ss";

	/**
	 * yyyyMMdd
	 */
	public static final String PATTERN_NORMAL_DATE_EIGHT = "yyyyMMdd";

	/**
	 * yyyyMM
	 */
	public static final String PATTERN_NORMAL_MONTH_SIX = "yyyyMM";

	/**
	 * yyyy
	 */
	public static final String PATTERN_NORMAL_YEAR_FOUR = "yyyy";

	/**
	 * MM
	 */
	public static final String PATTERN_NORMAL_MONTH_TWO = "MM";

	/**
	 * yyyyMMddHHmmssSSS
	 */
	public static final String PATNER_TIMESTAMP = "yyyyMMddHHmmssSSS";

	/**
	 * 校验年度格式 yyyy
	 * 
	 * @author huanglu1
	 * @date 2018年4月29日
	 * @param year
	 * @return
	 */
	public static boolean checkYearStr(String year) {
		return StringUtils.isNumeric(year) && 4 == year.length();
	}

	/**
	 * 校验月份格式MM
	 * 
	 * @author huanglu1
	 * @date 2018年4月29日
	 * @param month
	 * @return
	 */
	public static boolean checkMonthStr(String month) {
		return StringUtils.isNumeric(month) && 2 == month.length() && 13 > Integer.parseInt(month);
	}

	/**
	 * 校验年月格式 yyyyMM
	 * 
	 * @author huanglu1
	 * @date 2018年4月29日
	 * @param yearMonth
	 * @return
	 */
	public static boolean checkYearMonthStr(String yearMonth) {
		if (!StringUtils.isNumeric(yearMonth) || 6 != yearMonth.length()) {
			return false;
		}
		return 13 > Integer.parseInt(yearMonth.substring(4, 6));
	}

	/**
	 * 获取当前日期
	 * 
	 * @author huanglu1
	 * @date 2018年4月29日
	 * @return
	 */
	public static Date getCurrentDate() {
		return getCurrentDate(true);
	}

	/**
	 * 返回当前日期（格式：yyyy-MM-dd HH:mm:ss）
	 * 
	 * @param hms
	 *        是否包含时分秒毫秒
	 * @return 系统当前时间
	 */
	public static Date getCurrentDate(boolean hms) {
		Calendar currentDate = Calendar.getInstance();
		if (!hms) {
			currentDate.set(Calendar.HOUR_OF_DAY, 0);
			currentDate.set(Calendar.MINUTE, 0);
			currentDate.set(Calendar.SECOND, 0);
			currentDate.set(Calendar.MILLISECOND, 0);
		}
		return currentDate.getTime();
	}

	/**
	 * 获取当前年份
	 * 
	 * @author huanglu1
	 * @date 2018年4月29日
	 * @return yyyy
	 */
	public static String getCurrentYear() {
		return convertDate2TargetPattern(getCurrentDate(), PATTERN_NORMAL_YEAR_FOUR);
	}

	/**
	 * 获取当前年月
	 * 
	 * @author huanglu1
	 * @date 2018年4月29日
	 * @return yyyyMM
	 */
	public static String getCurrentYearMonth() {
		return convertDate2TargetPattern(getCurrentDate(), PATTERN_NORMAL_MONTH_SIX);
	}

	/**
	 * 获取年月，根据日期和月份查
	 * 
	 * @author huanglu1
	 * @date 2018年8月30日
	 * @param date
	 *        日期
	 * @param amount
	 *        针对日期增加的月份
	 * @return yyyyMM
	 */
	public static String getYearMonthByDateAndAddMonths(Date date, int amount) {
		Date yearMonth = DateUtils.addMonths(date, amount);
		return convertDate2TargetPattern(yearMonth, PATTERN_NORMAL_MONTH_SIX);
	}

	/**
	 * 获取输入年月的第一天
	 * 
	 * @author huanglu1
	 * @date 2018年9月1日
	 * @param yearMonth
	 *        yyyyMM
	 * @return yyyyMMdd
	 */
	public static String getFirstDayOfMonth(String yearMonth) {
		if (checkYearMonthStr(yearMonth)) {
			return yearMonth + "01";
		}
		return StringUtils.EMPTY;
	}

	/**
	 * 获取输入年月的最后一天
	 * 
	 * @author huanglu1
	 * @date 2018年9月1日
	 * @param yearMonth
	 *        yyyyMM
	 * @return yyyyMMdd
	 */
	public static String getLastDayOfMonth(String yearMonth) {
		String firstDayStr = getFirstDayOfMonth(yearMonth);
		Date firstDay = convertDateStr2Date(firstDayStr, PATTERN_NORMAL_DATE_EIGHT);
		if (null == firstDay) {
			return StringUtils.EMPTY;
		}
		Date nextMonthFirstDay = DateUtils.addMonths(firstDay, 1);
		Date lastDay = DateUtils.addDays(nextMonthFirstDay, -1);
		return convertDate2TargetPattern(lastDay, PATTERN_NORMAL_DATE_EIGHT);
	}

	/**
	 * 获取一年最后一天
	 * 
	 * @author huanglu1
	 * @date 2018年5月17日
	 * @param year
	 * @return
	 */
	public static Date getLastDayByYear(String year) {
		if (!checkYearStr(year)) {
			return null;
		}
		String lastDay = year + "1231";
		return convertDateStr2Date(lastDay, PATTERN_NORMAL_DATE_EIGHT);
	}

	/**
	 * 转换日期为目标格式
	 * 
	 * @author huanglu1
	 * @date 2018年4月29日
	 * @param srcDate
	 * @param targetPattern
	 * @return
	 */
	public static String convertDate2TargetPattern(Date srcDate, String targetPattern) {
		if (null == srcDate || StringUtils.isBlank(targetPattern)) {
			return StringUtils.EMPTY;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(targetPattern);
		return sdf.format(srcDate);
	}

	/**
	 * 转换源日期格式字符串为日期
	 * 
	 * @author huanglu1
	 * @date 2018年4月29日
	 * @param srcDateStr
	 * @param srcPattern
	 * @return
	 */
	public static Date convertDateStr2Date(String srcDateStr, String srcPattern) {
		if (StringUtils.isBlank(srcDateStr) || StringUtils.isBlank(srcPattern)) {
			return null;
		}
		try {
			return DateUtils.parseDate(srcDateStr, srcPattern);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 转换源日期格式字符为目标格式
	 * 
	 * @author huanglu1
	 * @date 2018年4月29日
	 * @param srcDateStr
	 * @param srcPattern
	 * @param targetPattern
	 * @return
	 */
	public static String convertDateStr2TargetPattern(String srcDateStr, String srcPattern, String targetPattern) {
		Date d = convertDateStr2Date(srcDateStr, srcPattern);
		if (null == d || StringUtils.isBlank(targetPattern)) {
			return StringUtils.EMPTY;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(srcPattern);
		sdf.applyPattern(targetPattern);
		return sdf.format(d);
	}

	/**
	 * 获取年月列表根据年度
	 * 
	 * @author huanglu1
	 * @date 2018年4月29日
	 * @param year
	 *        yyyy
	 * @return
	 */
	public static List<String> getYearMonthListByYear(String year) {
		if (!SccbvDateUtils.checkYearStr(year)) {
			return Collections.emptyList();
		}
		List<String> yearMonthList = new ArrayList<>();
		for (String month : StringConvertUtils.MONTH) {
			yearMonthList.add(year + month);
		}
		return yearMonthList;
	}

	/**
	 * 获取年月列表根据开始年月和结束年月
	 * 
	 * @author huanglu1
	 * @date 2018年4月29日
	 * @param yearMonthStart
	 *        yyyyMM
	 * @param yearMonthEnd
	 *        yyyyMM
	 * @return
	 */
	public static List<String> getYearMonthListByYearMonth(String yearMonthStart, String yearMonthEnd) {
		if (!SccbvDateUtils.checkYearMonthStr(yearMonthStart) || !SccbvDateUtils.checkYearMonthStr(yearMonthEnd)
				|| yearMonthStart.compareTo(yearMonthEnd) > 0) {
			return Collections.emptyList();
		}
		List<String> yearMonthList = new ArrayList<>();
		int startYearInt = Integer.parseInt(yearMonthStart.substring(0, 4));
		int startMonthIdx = Integer.parseInt(yearMonthStart.substring(4, 6));
		for (int i = startMonthIdx - 1; i <= 12; i++) {
			String year = String.valueOf(startYearInt);
			if (i == 12) {
				startYearInt++;
				i = -1;
				continue;
			}
			String yearMonth = year + StringConvertUtils.MONTH[i];
			yearMonthList.add(yearMonth);
			if (yearMonth.compareTo(yearMonthEnd) == 0) {
				break;
			}
		}
		return yearMonthList;
	}

	public static void main(String[] args) {
		System.out.println("------------check---------------");
		System.out.println("2018>>>" + checkYearStr("2018"));
		System.out.println("13>>>" + checkMonthStr("13"));
		System.out.println("1>>>" + checkMonthStr("1"));
		System.out.println("01>>>" + checkMonthStr("01"));
		System.out.println("201813>>>" + checkYearMonthStr("201813"));
		System.out.println("------------getCurrent---------------");
		System.out.println(getCurrentDate());
		System.out.println(getCurrentDate(false));
		System.out.println(getCurrentYear());
		System.out.println(getCurrentYearMonth());
		System.out.println("------------get---------------");
		System.out.println(getLastDayByYear("2018"));
		System.out.println(getLastDayByYear("XXXX"));
		System.out.println(
				getYearMonthByDateAndAddMonths(convertDateStr2Date("2018-03-31", PATTERN_NORMAL_DATE_TEN), -1));
		System.out.println(getFirstDayOfMonth("201802"));
		System.out.println(getFirstDayOfMonth("XX"));
		System.out.println(getLastDayOfMonth("201802"));
		System.out.println(getLastDayOfMonth("XXX"));
		System.out.println("------------convert---------------");
		System.out.println(convertDate2TargetPattern(getCurrentDate(), PATTERN_NORMAL_DATETIME_NINETEEN));
		System.out.println(convertDateStr2Date("2018-04-29 01:02:03", PATTERN_NORMAL_DATETIME_NINETEEN));
		System.out.println(convertDateStr2TargetPattern("2018-04-29 01:02:03", PATTERN_NORMAL_DATETIME_NINETEEN,
				PATTERN_NORMAL_DATE_EIGHT));
		System.out.println("------------getYearMonthList---------------");
		System.out.println(getYearMonthListByYear("2018").toString());
		System.out.println(getYearMonthListByYear("2018 ").toString());
		System.out.println(getYearMonthListByYear(null).toString());
		System.out.println(getYearMonthListByYearMonth("201806", "201801"));
		System.out.println(getYearMonthListByYearMonth("201804", "201803"));
		System.out.println(getYearMonthListByYearMonth("201804", "201804"));
		System.out.println(getYearMonthListByYearMonth("201812", "201904"));
		System.out.println(getYearMonthListByYearMonth("201804", "202004"));
	}
}
